﻿using Devonline.Entity;

namespace Devonline.Communication.Messages;

/// <summary>
/// 消息通讯器接口
/// </summary>
/// <typeparam name="TMessage">消息类型</typeparam>
/// <typeparam name="TKey">主键类型</typeparam>
/// <typeparam name="TContent">消息内容类型</typeparam>
public interface IMessageCommunicator<TMessage, TKey, TContent> : ICommunicator<TMessage> where TMessage : class, IMessage<TKey, TContent>
{
    /// <summary>
    /// 收到已读消息时执行的事件处理委托方法
    /// </summary>
    event EventHandler<TMessage>? Read;
    /// <summary>
    /// 收到回执消息时执行的事件处理委托方法
    /// </summary>
    event EventHandler<TMessage>? Ack;

    /// <summary>
    /// 仅发送文本消息到默认接收者的方法
    /// </summary>
    /// <param name="content"></param>
    /// <returns></returns>
    Task<TMessage?> SendAsync(TContent content);
    /// <summary>
    /// 仅发送指定类型的消息内容到默认接收者的方法
    /// </summary>
    /// <param name="content"></param>
    /// <param name="type">消息类型</param>
    /// <returns></returns>
    Task<TMessage?> SendAsync(TContent content, MessageType type = MessageType.Text);

    /// <summary>
    /// 仅发送文本消息到指定接收者
    /// 消息接收者为指定接收者或所有人
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="receiver">消息接收者, null or empty: 所有人</param>
    /// <returns></returns>
    Task<TMessage?> SendAsync(TContent content, TKey? receiver = default);
    /// <summary>
    /// 发送指定类型消息内容发送到指定消息接收者
    /// 消息接收者为指定接收者或所有人
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="receiver">消息接收者, null or empty: 所有人</param>
    /// <param name="type">消息类型</param>
    /// <returns></returns>
    Task<TMessage?> SendAsync(TContent content, TKey? receiver = default, MessageType type = MessageType.Text);
    /// <summary>
    /// 缓存更新
    /// 缓存消息接收者为指定接收者或所有人
    /// </summary>
    /// <param name="cache"></param>
    /// <returns></returns>
    Task<TMessage?> RefreshCacheAsync(TContent cache, TKey? receiver = default);

    /// <summary>
    /// 将通知内容发送到到默认消息接收者或指定消息接收者
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="receiver">消息接收者</param>
    /// <returns></returns>
    Task<TMessage?> NoticeAsync(TContent content, TKey? receiver = default);
    /// <summary>
    /// 将告警内容发送到到默认消息接收者或指定消息接收者
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="receiver">消息接收者</param>
    /// <returns></returns>
    Task<TMessage?> WarningAsync(TContent content, TKey? receiver = default);
    /// <summary>
    /// 将错误内容发送到到默认消息接收者或指定消息接收者
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="receiver">消息接收者</param>
    /// <returns></returns>
    Task<TMessage?> ErrorAsync(TContent content, TKey? receiver = default);

    /// <summary>
    /// 执行指令/命令
    /// 指令接收者为指定接收者或默认接收者
    /// </summary>
    /// <param name="type">指令类型</param>
    /// <param name="receiver">指令接收者</param>
    /// <param name="content">指令内容</param>
    /// <returns></returns>
    Task<TMessage?> ExecuteAsync(MessageType type = MessageType.Execute, TKey? receiver = default, TContent? content = default);

    /// <summary>
    /// 发送回复消息
    /// 消息接收者为原始消息发送者
    /// </summary>
    /// <param name="content">消息内容</param>
    /// <param name="message">回复的消息</param>
    /// <param name="type">消息类型</param>
    /// <returns></returns>
    Task<TMessage?> ReplyAsync(TContent content, TMessage message, MessageType type = MessageType.Text);
    /// <summary>
    /// 发送已读消息
    /// 消息接收者为原始消息发送者
    /// </summary>
    /// <param name="id">消息编号</param>
    /// <returns></returns>
    Task ReadAsync(TKey id);

    /// <summary>
    /// 获取在线用户
    /// </summary>
    /// <returns></returns>
    Task<TMessage?> GetOnlineUsersAsync();
}

/// <summary>
/// 文本消息通讯器接口
/// </summary>
public interface IMessageCommunicator : IMessageCommunicator<Message, string, string> { }